package com.leinao.interceptor;

import com.leinao.commons.Response;
import com.leinao.config.EnvironmentConfig;
import com.leinao.config.RedisCacheConfig;
import com.leinao.constant.Constant;
import com.leinao.constant.ImageErrorEnum;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


/**
 * 
 * 在访问controller前判断是否登录，返回json，不进行重定向。
 *
 * @author  wangshoufa
 * @date 2018年11月15日 下午1:30:19
 */
@Component
@Aspect
public class SecurityAuthInterceptor {

	private static Logger logger = LoggerFactory.getLogger(SecurityAuthInterceptor.class);

	@Autowired
	public HttpServletRequest request;
	@Autowired
	RedisCacheConfig redisCacheConfig;
	@Autowired
	EnvironmentConfig env;

	/**
	 * 拦截方法表达式
	 */
	@Pointcut("execution(* com.leinao.*.controller.*.*(..)) ")
	public void loginJudgementControllerMethodPointcut() {
		logger.debug("loginJudgementControllerMethodPointcut用户是否登陆切面");
	}

	/**
	 * 校验token信息是否合法
	 */
	@SuppressWarnings("unchecked")
	@Around("loginJudgementControllerMethodPointcut()")
	public Response<Object> loginInterceptor(ProceedingJoinPoint pjp) {
		Object[] args = pjp.getArgs();
		Response<Object> returnMsg = new Response<Object>();
		String methodName = pjp.getSignature().getName();// 返回当前连接点签名的名称 当前方法的名称

		// 获取请求token信息
		String token = request.getHeader(Constant.USER_TOKEN);
		String bitaToken = request.getHeader(Constant.USER_BITA_TOKEN);
		logger.info("pai token: {}, bitaToken: {}", token, bitaToken);
		Jedis jedis = null;
		try {
			HttpSession session = request.getSession();
			String userInfo = (String) session.getAttribute(Constant.USER_SESSION);
			if(StringUtils.isBlank(userInfo)) {
				JedisPool jedisPool = redisCacheConfig.getJedisPool();
				jedis = jedisPool.getResource();
				logger.debug("get redisResource success");
				String bitaKey = env.getPrefix() + bitaToken;
				String paiKey = env.getPrefix() + token;
				String bitaValue = jedis.get(bitaKey);
				String paiValue = jedis.get(paiKey);
				if (StringUtils.isBlank(bitaValue) || StringUtils.isBlank(paiValue)) {
					logger.debug("redis token data bitaValue: {}, paiValue: {}", bitaValue, paiValue);
					return Response.error(Constant.RESPONSE_STATUS_NO_AUTHORITY, ImageErrorEnum.LOGIN_TIMEOUT.getSeq(), ImageErrorEnum.LOGIN_TIMEOUT.getDesc(), null);
				}
				session.setMaxInactiveInterval(env.getExpireSeconds());
				session.setAttribute(Constant.USER_SESSION, paiValue);
			}
			try {
	            returnMsg = (Response<Object>) pjp.proceed(args);
	            logger.debug("out response------" + methodName + " : " + returnMsg);
	        } catch (Throwable e) {
	        	logger.error("get requestBody failed", e);
	        }
			return returnMsg;
		} catch (Exception e) {
			logger.error("get redisResource failed", e);
			return Response.error(Constant.RESPONSE_STATUS_SERVER_ERROR, ImageErrorEnum.REDIS_RESOURCE_ERROR.getSeq(), ImageErrorEnum.REDIS_RESOURCE_ERROR.getDesc(), null);
		} finally {
			if (jedis != null) {
				jedis.close();
			}
			logger.debug("login info check finished");
		}
	}

}